package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.dubbo.pojo.Comment;
import com.tanhua.dubbo.pojo.UserInfo;
import com.tanhua.dubbo.pojo.Video;
import com.tanhua.dubbo.vo.PageInfo;
import com.tanhua.server.vo.CommentVo;
import com.tanhua.server.vo.PageResult;
import com.tanhua.server.vo.VideoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class VideoService {

    @DubboReference(version = "1.0.0")
    private VideoApi videoApi;

    @Autowired
    private PicUploadService picUploadService;

    @Autowired
    protected FastFileStorageClient storageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @Autowired
    private VideoMQService videoMQService;

    public Object saveVideo(MultipartFile picFile, MultipartFile videoFile) {
        Long userId = UserThreadLocal.get();

        Video video = new Video();
        video.setUserId(userId);

        //上传图片
        PicUploadResult uploadResult = this.picUploadService.upload(picFile);
        if (StrUtil.isEmpty(uploadResult.getName())) {
            return ErrorResult.builder().errCode("500")
                    .errMessage("上传视频封面图片失败，请重试！").build();
        }

        video.setPicUrl(uploadResult.getName()); //图片

        try {
            //上传小视频
            String fileExtName = StrUtil.subAfter(videoFile.getOriginalFilename(), '.', true);
            StorePath storePath = this.storageClient.uploadFile(videoFile.getInputStream(), videoFile.getSize(), fileExtName, null);
            video.setVideoUrl(this.fdfsWebServer.getWebServerUrl() + storePath.getFullPath());
        } catch (Exception e) {
            log.error("上传视频文件失败，userId = {}, file = {}", userId, videoFile.getOriginalFilename(), e);
            return ErrorResult.builder().errCode("501")
                    .errMessage("上传视频文件失败，请重试！").build();
        }

        String videoId = this.videoApi.saveVideo(video);
        if (StrUtil.isEmpty(videoId)) {
            return ErrorResult.builder().errCode("502")
                    .errMessage("保存小视频数据失败，请重试！").build();
        }
        //发送发布成功的消息
        this.videoMQService.videoMsg(videoId);

        return null;
    }

    /**
     * 查询小视频列表
     *
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult queryVideoList(Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long userId = UserThreadLocal.get();
        PageInfo<Video> pageInfo = this.videoApi.queryVideoList(userId, page, pageSize);
        List<Video> records = pageInfo.getRecords();

        if (CollUtil.isEmpty(records)) {
            //给出默认推荐视频
            PageInfo<Video> videoList1 = this.videoApi.defaultVideoList(userId, page, pageSize);
            List<Video> records1 = videoList1.getRecords();
            List<UserInfo> userInfoList = this.userInfoApi.queryByUserIdList(CollUtil.getFieldValues(records, "userId"));
            List<VideoVo> videoList = new ArrayList<>();
            for (Video video : records1) {
                VideoVo videoVo = BeanUtil.toBeanIgnoreError(video, VideoVo.class);
                //查询用户
                for (UserInfo userInfo : userInfoList) {
                    if (ObjectUtil.equal(userInfo.getUserId(), video.getUserId())){
                        //属性值拷贝
                        BeanUtil.copyProperties(userInfo,videoVo,"id","userId");
                        break;
                    }
                }
                videoList.add(videoVo);
            }
            pageResult.setItems(videoList);

            return pageResult;
        }

        //查询用户信息
        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(CollUtil.getFieldValues(records, "userId"));

        List<VideoVo> videoVoList = new ArrayList<>();
        records.forEach(video -> {
            VideoVo videoVo = BeanUtil.toBeanIgnoreError(video, VideoVo.class);
            //查询用户
            UserInfo userInfo = userInfoMap.get(videoVo.getUserId());


            String s = Convert.toStr(videoVo.getUserId());
            videoVo.setSignature("我就是"+s+",不一样的"+s); // 签名

            videoVo.setHasFocus(this.videoApi.isFocus(userId, Convert.toStr(videoVo.getUserId())) ? 1 : 0); //是否关注
            videoVo.setCommentCount(this.videoApi.queryCommentCount(videoVo.getId())); // 评论数
            videoVo.setHasLiked(this.videoApi.queryUserIsLike(userId, videoVo.getId()) ? 1 : 0); //是否点赞（1是，0否）
            videoVo.setLikeCount(Convert.toInt(this.videoApi.queryLikeCount(videoVo.getId())));//点赞数


            //属性值拷贝
            BeanUtil.copyProperties(userInfo, videoVo, "id", "userId");
            videoVoList.add(videoVo);
        });

        pageResult.setItems(videoVoList);
        return pageResult;
    }

    public Long likeComment(String publishId) {
        Long userId = UserThreadLocal.get();
        //点赞
        Boolean result = this.videoApi.likeComment(userId, publishId);
        if (result) {
            //发送点赞成功的消息
            this.videoMQService.likeVideoMsg(publishId);

            //查询点赞数
            return this.videoApi.queryLikeCount(publishId);
        }
        return 0L;
    }

    public Long disLikeComment (String publishId) {
        Long userId = UserThreadLocal.get();
        //取消点赞
        Boolean result = this.videoApi.disLikeComment(userId, publishId);
        if (result) {
            //发送取消点赞的消息
            this.videoMQService.disLikeVideoMsg(publishId);

            //查询点赞数
            return this.videoApi.queryLikeCount(publishId);
        }
        return 0L;
    }


    /**
     * 查询评论列表
     * @param videoId 视频id
     * @return
     */
    public PageResult queryCommentList(String videoId,
                               Integer page,
                               Integer pageSize) {

        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);

        Long userId = UserThreadLocal.get();

        //查询评论列表
        PageInfo<Comment> pageInfo = this.videoApi.queryCommentList(videoId,page,pageSize);


        List<Comment> records = pageInfo.getRecords();

        //评论列表飞空判断
        if (CollUtil.isEmpty(records)){
            return pageResult;
        }

        //查询用户信息
        List<Object> userIdList = CollUtil.getFieldValues(records, "userId");
        List<UserInfo> userInfoList = this.userInfoApi.queryByUserIdList(userIdList);

        ArrayList<CommentVo> result = new ArrayList<>();
        for (Comment record : records) {
            CommentVo commentVo = new CommentVo();
            commentVo.setContent(record.getContent());
            commentVo.setId(record.getId().toHexString());
            commentVo.setCreateDate(DateUtil.format(new Date(record.getCreated()), "HH:mm"));
            //是否点赞
            commentVo.setHasLiked(this.videoApi.queryUserIsLike(userId, commentVo.getId()) ? 1 : 0);
            //点赞数
            commentVo.setLikeCount(Convert.toInt(this.videoApi.queryLikeCount(commentVo.getId())));

            for (UserInfo userInfo : userInfoList) {
                if(ObjectUtil.equals(record.getUserId(), userInfo.getUserId())){
                    commentVo.setAvatar(userInfo.getLogo());
                    commentVo.setNickName(userInfo.getNickName());
                    break;
                }
            }
            result.add(commentVo);
        }
        pageResult.setItems(result);
        return pageResult;
    }

    /**
     * 评论发布
     * @param publishId 目标id
     * @param comment 评论内容
     * @return
     */
    public Boolean publishComment(String publishId, Map<String,String> comment) {
        Long userId = UserThreadLocal.get();

        return this.videoApi.publishComment(publishId,comment,userId);

    }

    public Object userFocus(String uid) {
        Boolean focus = this.isFocus(uid);
        if (focus){
            return null;
        }
        Long userId = UserThreadLocal.get();
        return this.videoApi.userFocus(userId,uid);
    }

    public Object userUnFocus(String uid) {
        return null;
    }

    public Boolean isFocus(String uid){
        Long userId = UserThreadLocal.get();

        return this.videoApi.isFocus(userId,uid);
    }
}
